home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
raytrace
/
rayshade
/
graphtal.lzh
/
Graphtal.Amiga
/
RayshadeDevice.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-17
|
8KB
|
282 lines
/*
* RayshadeDevice.C - rayshade device driver.
*
* Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
* University of Berne, Switzerland
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
*/
#include <stdlib.h>
#include "RayshadeDevice.h"
#include "ViewTransform.h"
#include "Polygon.h"
static const char* colorFile = "colors.ray.def";
//___________________________________________________________ RayshadeDevice
RayshadeDevice::RayshadeDevice(Options* options)
: DeviceDriver(options), currentColor("Noname"), applyTexture(0),
savePrimitives(0), saveDefFile(NULL)
{
if (theOptions->oname == "cout") {
Error(ERR_ADVISE,
"No file name specified: using default.ray and default.ray.def");
theOptions->oname = "default.ray";
}
rayFile = fopen(theOptions->oname, "w");
if (rayFile == NULL)
Error(ERR_PANIC, "can't open file " + theOptions->oname);
defFile = fopen(theOptions->oname + ".def", "w");
if (defFile == NULL)
Error(ERR_PANIC, "can't open file " + theOptions->oname + ".def\n");
}
RayshadeDevice::~RayshadeDevice()
{
StringTable_Iterator macroItr(macroNames);
while(macroItr.more()){
delete macroItr.cur_value();
macroItr.next();
}
}
void RayshadeDevice::begin()
{
fprintf(defFile, "#ifndef %s_DEF\n", LSystemName.chars());
fprintf(defFile, "# define %s_DEF\n\n", LSystemName.chars());
fprintf(defFile, "name %s\n", LSystemName.chars());
fprintf(defFile, "/* primitives: \n");
fprintf(defFile, "grid \n");
}
void RayshadeDevice::end(const BoundingBox& b)
{
long gridsize = (long)pow(primitives, 1./3.);
fprintf(defFile, "end\n\n");
fprintf(defFile, "#endif\n");
/*
* Number of primitives in this object.
*/
fseek(defFile, 3*LSystemName.length()+49, 0);
fprintf(defFile, "%ld */", primitives);
/*
* Resulting grid size.
*/
fseek(defFile, 3*LSystemName.length()+67, 0);
fprintf(defFile, "%ld %ld %ld", gridsize, gridsize, gridsize);
fclose(defFile);
defFile = NULL;
Vector eye, lookat, up;
if (theOptions->autoscale) {
ViewTransform* view
= new ViewTransform(b, theOptions->up, theOptions->fov,
theOptions->resX, theOptions->resY);
eye = view->getEye(); lookat = view->getLookat(); up = view->getUp();
delete view;
}
else {
eye = theOptions->eye; lookat = theOptions->lookat; up = theOptions->up;
}
if (theOptions->verbose)
cerr << "primitives: "<< primitives << '\n';
fprintf(rayFile, "/* This file was produced by graphtal ... so don't wonder.\n");
fprintf(rayFile, " -------------------------------------------------------\n\n");
fprintf(rayFile, " bounding volume:\n");
fprintf(rayFile, " X: %.4g to %.4g\n", b.xmin(), b.xmax());
fprintf(rayFile, " Y: %.4g to %.4g\n", b.ymin(), b.ymax());
fprintf(rayFile, " Z: %.4g to %.4g\n", b.zmin(), b.zmax());
fprintf(rayFile, " %ld primitives\n", primitives);
fprintf(rayFile, "*/\n\n");
fprintf(rayFile, "screen %d %d\n", theOptions->resX, theOptions->resY);
fprintf(rayFile, "maxdepth 1\n");
fprintf(rayFile, "sample 1\n\n");
fprintf(rayFile, "eyep %.4g %.4g %.4g\n", eye[0], eye[1], eye[2]);
fprintf(rayFile, "lookp %.4g %.4g %.4g\n", lookat[0], lookat[1], lookat[2]);
fprintf(rayFile, "up %.4g %.4g %.4g\n", up[0], up[1], up[2]);
fprintf(rayFile, "fov %.4g\n\n", theOptions->fov);
fprintf(rayFile, "light 1.0 point %.4g %.4g %.4g\n\n", eye[0], eye[1], eye[2]);
fprintf(rayFile, "#define s sphere\n");
fprintf(rayFile, "#define cl cylinder\n");
fprintf(rayFile, "#define c cone\n");
fprintf(rayFile, "#define p poly\n");
fprintf(rayFile, "#define o object\n");
fprintf(rayFile, "#define t transform\n");
fprintf(rayFile, "#define a applysurf\n\n");
fprintf(rayFile, "#include \"%s\"\n\n", colorFile);
StringTable_Iterator macroItr(macroNames);
StringTable_Iterator libraryItr(libraryNames);
while(libraryItr.more()){
fprintf(rayFile, "#include \"%s.ray.lib\"\n\n", libraryItr.cur_key().chars());
libraryItr.next();
}
while(macroItr.more()){
fprintf(rayFile, "#include \"%s.ray.def\"\n\n", macroItr.cur_key().chars());
macroItr.next();
}
fprintf(rayFile, "#include \"%s\"\n\n",
(theOptions->oname + rcString(".def")).chars());
fprintf(rayFile, "o %s\n\n", LSystemName.chars());
fclose(rayFile);
}
void RayshadeDevice::cylinder(const Vector& p1, const Vector& p2, real r)
{
primitives++;
fprintf(defFile, "cl %.4g %.4g %.4g %.4g %.4g %.4g %.4g\n",
r, p1[0], p1[1], p1[2], p2[0], p2[1], p2[2]);
if (applyTexture)
fprintf(defFile, "%s\n", currentTexture.chars());
}
void RayshadeDevice::cone(const Vector& p1, real r1, const Vector& p2, real r2)
{
primitives++;
fprintf(defFile, "c %.4g %.4g %.4g %.4g %.4g %.4g %.4g %.4g\n",
r1, p1[0], p1[1], p1[2], r2, p2[0], p2[1], p2[2]);
if (applyTexture)
fprintf(defFile, "%s\n", currentTexture.chars());
}
void RayshadeDevice::polygon(Polygon* p)
{
primitives++;
fprintf(defFile, "p\n");
for (register int i=0; i<p->numVertices(); i++) {
const Vector& P = p->vertex(i);
fprintf(defFile, "\t%.4g %.4g %.4g\n", P[0], P[1], P[2]);
}
delete p;
if (applyTexture)
fprintf(defFile, "%s\n", currentTexture.chars());
}
void RayshadeDevice::sphere(const Vector& p, real r)
{
primitives++;
fprintf(defFile, "s %.4g %.4g %.4g %.4g\n", r, p[0], p[1], p[2]);
if (applyTexture)
fprintf(defFile, "%s\n", currentTexture.chars());
}
void RayshadeDevice::color(const Color& c)
{
if (c.colorName() != currentColor) {
currentColor = c.colorName();
fprintf(defFile, "a %s\n", currentColor.chars());
}
}
void RayshadeDevice::texture(const rcString& t)
{
currentTexture = t;
applyTexture = !currentTexture.empty();
}
void RayshadeDevice::beginMacro(const rcString& macroName)
{
currentMacroName = macroName;
savePrimitives = primitives;
primitives = 0;
currentColor = "Noname";
saveDefFile = defFile;
defFile = fopen(macroName + ".ray.def", "w");
if (defFile == NULL)
Error(ERR_PANIC, "can't open file " + macroName + ".ray.def\n");
fprintf(defFile, "#ifndef %s_DEF\n", macroName.chars());
fprintf(defFile, "# define %s_DEF\n\n", macroName.chars());
fprintf(defFile, "name %s\n", macroName.chars());
fprintf(defFile, "/* primitives: \n");
fprintf(defFile, "grid \n");
}
void RayshadeDevice::endMacro()
{
long gridsize = (long)pow(primitives, 1./3.);
fprintf(defFile, "end\n\n");
fprintf(defFile, "#endif\n");
/*
* Number of primitives in this object.
*/
fseek(defFile, 3*currentMacroName.length()+49, 0);
fprintf(defFile, "%ld */", primitives);
/*
* Resulting grid size.
*/
fseek(defFile, 3*currentMacroName.length()+67, 0);
fprintf(defFile, "%ld %ld %ld", gridsize, gridsize, gridsize);
fclose(defFile);
defFile = saveDefFile;
saveDefFile = NULL;
long* num = new long;
*num = primitives;
macroNames.find_and_replace(currentMacroName, num);
primitives = savePrimitives;
}
void RayshadeDevice::executeMacro(const rcString& macroName, const TransMatrix& tmat)
{
void* numPrimitives;
if (!macroNames.lookup(macroName, numPrimitives))
Error(ERR_PANIC, "RayshadeDevice::executeMacro: macro "
+ macroName + " does not exist");
primitives += *((long*)numPrimitives);
object(macroName, tmat);
}
void RayshadeDevice::libraryObject(const rcString& objectName, const TransMatrix& tmat)
{
object(objectName, tmat);
}
void RayshadeDevice::object(const rcString& name, const TransMatrix& tmat)
{
fprintf(defFile, "o %s\n", name.chars());
fprintf(defFile, "\tt\t%.4g %.4g %.4g\n\t\t%.4g %.4g %.4g\n",
tmat(0,0), tmat(0,1), tmat(0,2),
tmat(1,0), tmat(1,1), tmat(1,2));
fprintf(defFile, "\t\t%.4g %.4g %.4g\n\t\t%.4g %.4g %.4g\n",
tmat(2,0), tmat(2,1), tmat(2,2),
tmat(3,0), tmat(3,1), tmat(3,2));
}